package com.ht.api.oss;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import org.apache.commons.codec.binary.Base64;
import org.apache.http.util.TextUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.PolicyConditions;

/**
 * @author zouhuu
 * @description 阿里云对象存储上传工具类
 * @date 2022/06/16 14:21:12
 */
@Component
public class AliyunOssUploadUtils {

    private static AliyunOssConfig aliyunOssConfig;

    /**
     * 使用构造方法注入配置信息
     */
    @Autowired
    public AliyunOssUploadUtils(AliyunOssConfig aliyunOssConfig) {
        AliyunOssUploadUtils.aliyunOssConfig = aliyunOssConfig;
    }


    /**
     * 获取前端上传签名
     * @return 结果
     */
    public static OSSPolicy getPolicy(String pathKey) {
        String subDir = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd")) + "/";
        String path = String.format("uploads/%s/%s", pathKey, subDir);
        // 生成 OSSClient
        OSS ossClient = new OSSClientBuilder().build(aliyunOssConfig.getEndpoint(), aliyunOssConfig.getAccessKeyId(), aliyunOssConfig.getAccessKeySecret());
        LocalDateTime localDateTime = LocalDateTime.now().plusSeconds(30);
        Date expiration = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
        PolicyConditions policyConditions = new PolicyConditions();
        policyConditions.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
        policyConditions.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, path);
        String postPolicy = ossClient.generatePostPolicy(expiration, policyConditions);
        String postSignature = ossClient.calculatePostSignature(postPolicy);
        byte[] binaryData = postPolicy.getBytes(StandardCharsets.UTF_8);
        String encodedPolicy = BinaryUtil.toBase64String(binaryData);
        String host =  aliyunOssConfig.getUrl();
        return OSSPolicy.builder().accessId(aliyunOssConfig.getAccessKeyId())
                .policy(encodedPolicy).signature(postSignature)
                .host(host)
                .domain(host)
                .dir(path)
                .expire(expiration.getTime())
                .build();
    }

    /**
     * 上传文件
     * @param base64String
     * @return
     * @throws Exception
     */
    public static String uploadFileByBase64(String base64String, String filePathName) throws Exception {
        // 生成 OSSClient
        OSS ossClient = new OSSClientBuilder().build(aliyunOssConfig.getEndpoint(), aliyunOssConfig.getAccessKeyId()
                , aliyunOssConfig.getAccessKeySecret());
        // 文件路径名称
        filePathName = aliyunOssConfig.getFilehost() + "/" + filePathName;
        try {
            ossClient.putObject(aliyunOssConfig.getBucketName(), filePathName, base64StringToInputStream(base64String));
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return aliyunOssConfig.getUrl() + "/" + filePathName;
    }

    /**
     * 上传文件
     * @param file
     * @return
     * @throws Exception
     */
    public static String uploadFile(File file, String filePathName) throws Exception {
        // 生成 OSSClient
        OSS ossClient = new OSSClientBuilder().build(aliyunOssConfig.getEndpoint(), aliyunOssConfig.getAccessKeyId()
                , aliyunOssConfig.getAccessKeySecret());
        // 文件路径名称
        filePathName = aliyunOssConfig.getFilehost() + "/" + filePathName;
        try {
            ossClient.putObject(aliyunOssConfig.getBucketName(), filePathName, new FileInputStream(file));
        } catch (Exception e) {
        	e.printStackTrace();
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return aliyunOssConfig.getUrl() + "/" + filePathName;
    }

    public static ByteArrayInputStream base64StringToInputStream(String base64String) {
        // 解码Base64字符串
        byte[] decodedBytes = Base64.decodeBase64(base64String);
        // 创建ByteArrayInputStream
        return new ByteArrayInputStream(decodedBytes);
    }

    /**
     * 转换url增加style
     * @param url   url地址
     * @return -
     */
    public static String transferUrlToStyle(String url) {
        if (TextUtils.isEmpty(url)) {
            return url;
        }
        String styleName = "style/andStyle";
//        String agent = ServletUtils.getRequest().getHeader("user-agent");
//        if (agent.contains("iPhone") || agent.contains("iPod") || agent.contains("iPad")) {
//            styleName = "style/iosStyle";
//        }
        if (!url.contains(styleName)) {
            url = url.concat("?x-oss-process=" + styleName);
        }
        return url;
    }

    /**
     * 批量转化
     * @param urls
     * @return
     */
    public static String transferBatchUrlToStyle(String urls) {
        if (!TextUtils.isEmpty(urls)) {
            List<String> album = Arrays.stream(urls.split(",")).collect(Collectors.toList());
            final int[] i = {0};
            album.forEach(e->{
                e = AliyunOssUploadUtils.transferUrlToStyle(e);
                album.set(i[0], e);
                i[0] = i[0] + 1;
            });
            urls = String.join(",", album);
        }
        return urls;
    }
}